use sea_orm_migration::prelude::*;

use crate::idents::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .create_table(
                Table::create()
                    .table(PendingJob::Table)
                    .col(ColumnDef::new(PendingJob::Id).uuid().primary_key())
                    .col(ColumnDef::new(PendingJob::CreatedAt).timestamp().not_null())
                    .col(ColumnDef::new(PendingJob::QueueName).text().not_null())
                    .col(
                        ColumnDef::new(PendingJob::Tries)
                            .small_integer()
                            .not_null()
                            .default(0),
                    )
                    .col(ColumnDef::new(PendingJob::LastTry).timestamp())
                    .col(ColumnDef::new(PendingJob::NextTryAfter).timestamp())
                    .col(ColumnDef::new(PendingJob::Payload).binary().not_null())
                    .to_owned(),
            )
            .await?;

        manager
            .create_index(
                Index::create()
                    .name("IDX_pending_job_on_created_at")
                    .table(PendingJob::Table)
                    .col(PendingJob::CreatedAt)
                    .if_not_exists()
                    .to_owned(),
            )
            .await?;

        manager
            .create_index(
                Index::create()
                    .name("IDX_pending_job_on_next_try_after")
                    .table(PendingJob::Table)
                    .col(PendingJob::NextTryAfter)
                    .if_not_exists()
                    .to_owned(),
            )
            .await?;

        manager
            .create_table(
                Table::create()
                    .table(CompletedJob::Table)
                    .col(ColumnDef::new(CompletedJob::Id).uuid().primary_key())
                    .col(
                        ColumnDef::new(CompletedJob::CreatedAt)
                            .timestamp()
                            .not_null(),
                    )
                    .col(ColumnDef::new(CompletedJob::QueueName).text().not_null())
                    .col(
                        ColumnDef::new(CompletedJob::CompletedAt)
                            .timestamp()
                            .not_null(),
                    )
                    .col(ColumnDef::new(CompletedJob::RunDuration).integer())
                    .col(ColumnDef::new(CompletedJob::TotalTries).small_integer())
                    .col(
                        ColumnDef::new(CompletedJob::Status)
                            .small_integer()
                            .not_null(),
                    )
                    .col(ColumnDef::new(CompletedJob::Msg).text())
                    .col(ColumnDef::new(CompletedJob::Payload).binary())
                    .to_owned(),
            )
            .await?;

        manager
            .create_index(
                Index::create()
                    .name("IDX_completed_job_on_created_at")
                    .table(CompletedJob::Table)
                    .col(CompletedJob::CreatedAt)
                    .if_not_exists()
                    .to_owned(),
            )
            .await?;

        manager
            .create_index(
                Index::create()
                    .name("IDX_completed_job_on_completed_at")
                    .table(CompletedJob::Table)
                    .col(CompletedJob::CompletedAt)
                    .if_not_exists()
                    .to_owned(),
            )
            .await?;

        Ok(())
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .drop_table(Table::drop().table(PendingJob::Table).to_owned())
            .await?;

        manager
            .drop_table(Table::drop().table(CompletedJob::Table).to_owned())
            .await?;

        Ok(())
    }
}
